package lt.marsrutai.mobile.android.service.impl;

import lt.marsrutai.mobile.android.service.ShapeManipulationService;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

/**
 * <p>Default implementation</p>
 * 
 * @author Justas
 *
 */
public class ShapeManipulationServiceImpl implements ShapeManipulationService {

    @Override
    public Drawable combineShapes(Resources resources, int shapeId, int overlayId, int targetColor) {
        Bitmap shapeBitmap = BitmapFactory.decodeResource(resources, shapeId);
        Bitmap gradientBitmap = BitmapFactory.decodeResource(resources, overlayId);
        
        // Create a mutable bitmap from the original
        shapeBitmap = shapeBitmap.copy(shapeBitmap.getConfig(), true);
        
        colorShape(shapeBitmap, targetColor);
        Bitmap combinedBitmap = combineImages(shapeBitmap, gradientBitmap);
        
        return new BitmapDrawable(resources, combinedBitmap);
    }
    
    /**
     * <p>Color a provided shape with a solid color.</p>
     * <p>All pixels will have their colors changed, while still preserving their transparency.</p> 
     * 
     * @param shape Shape which will have it's color changed
     * @param newShapeColor New shape color (transparency byte will be ignored)
     */
    private void colorShape(Bitmap shape, int newShapeColor) {
        for (int y = 0; y < shape.getHeight(); y++) {
            for (int x = 0; x < shape.getWidth(); x++) {
                // Extract shape's transparency byte
                int transparency = shape.getPixel(x, y) & 0xFF000000;
                
                // Keep each pixel's transparency, but change their color to newShapeColor
                int targetColor = newShapeColor & 0x00FFFFFF; 
                shape.setPixel(x, y, transparency | targetColor);
            }
        }
    }

    /**
     * <p>Combine two {@link Bitmap}s with the same dimensions.</p>
     * 
     * @param shape
     * @param overlay
     * @return
     */
    private Bitmap combineImages(Bitmap shape, Bitmap overlay) {
        Bitmap combinedImage = null;

        combinedImage = Bitmap.createBitmap(shape.getWidth(), shape.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas comboImage = new Canvas(combinedImage);

        // Put both shape and it's overlay on top of each other
        comboImage.drawBitmap(shape, 0f, 0f, null);
        comboImage.drawBitmap(overlay, 0f, 0f, null);

        return combinedImage;
    }
}
